1 module hip.gui.scroll_area;
2 import hip.gui.widget;
3 import hip.gui.button;
4 
5 
6 interface IRawScrollable
7 {
8     void onRawScroll(float[3] scroll);
9 }
10 
11 class ScrollArea : Widget, IRawScrollable
12 {
13     private static IWidgetRenderer DebugRenderer()
14     {
15         import hip.api.graphics.g2d.renderer2d;
16         __gshared DebugWidgetRenderer dbgRenderer;
17         if(dbgRenderer is null) dbgRenderer = new DebugWidgetRenderer(HipColor(85,85,85,85));
18         return dbgRenderer;
19     }
20     private IWidgetRenderer renderer;
21     private float scrollRate = -10, currentScroll = 0, lastScroll = 0;
22 
23     this(int width, int height)
24     {
25         this.width = width;
26         this.height = height;
27         renderer = DebugRenderer();
28     }
29 
30     override Bounds getWorldBounds(){return Bounds(worldTransform.x, worldTransform.y, width, height);}
31     void setRenderer(IWidgetRenderer renderer)
32     {
33         assert(renderer !is null);
34         this.renderer = renderer;
35     }
36 
37     void setScrollRate(float rate)
38     {
39         this.scrollRate = rate;
40     }
41 
42     void setScroll(float scroll)
43     {
44         lastScroll = currentScroll;
45         currentScroll = scroll;
46         foreach(ch; children)
47             ch.onScroll([0,currentScroll,0], [0,lastScroll,0]);
48     }
49 
50     void onRawScroll(float[3] scroll)
51     {
52         import hip.api;
53         setScroll(currentScroll + scroll[1]*scrollRate);
54     }
55 
56     override void onRender()
57     {
58         import hip.api.graphics.g2d.renderer2d;
59 
60         setStencilTestingEnabled(true);
61         setStencilTestingFunction(HipStencilTestingFunction.Always, 1, 0xFF);
62         setStencilOperation(HipStencilOperation.Keep, HipStencilOperation.Keep, HipStencilOperation.Replace);
63         setRendererColorMask(0,0,0,0);
64         fillRectangle(worldTransform.x, worldTransform.y, width, height);
65         setRendererColorMask(1,1,1,1);
66         setStencilTestingFunction(HipStencilTestingFunction.Equal, 1, 0xFF);
67         renderer.render(worldTransform.x, worldTransform.y, width, height);
68         foreach(ch; children)
69             ch.render();
70 
71         setStencilTestingEnabled(false);
72     }
73 }
74 
75 import hip.gui.linear_layout;
76 class ScrollBar : LinearLayout
77 {
78     private
79     {
80         Button backward;
81         Button thumb;
82         Button forward;
83     }
84 
85     ///Used to keep the layout size fixed
86     private Widget thumbFixer;
87     private int barSize = 50;
88     private int barRate = 1;
89     private float barScale = 1;
90     private int[2] buttonsDimensions;
91 
92     void setButtonsSize(int width, int height)
93     {
94         forward.width  = backward.width  = width;
95         forward.height = backward.height = height;
96     }
97 
98     void setBarSize(int size)
99     {
100         barSize = size;
101         setDimensionFromDirection(size);
102     }
103 
104     void setTarget(int* target)
105     {
106         backward.setOnClick((){*target = *target - barRate;});
107         forward.setOnClick((){*target = *target + barRate;});
108     }
109 
110     private void setDimensionFromDirection(int dimensionSize)
111     {
112         if(dir == LinearLayout.Direction.horizontal)
113         {
114             thumb.width = cast(int)(dimensionSize * barScale);
115             thumbFixer.width = dimensionSize;
116         }
117         else
118         {
119             thumb.height = cast(int)(dimensionSize * barScale);
120             thumbFixer.height = dimensionSize;
121         }
122     }
123 
124     void setBarScale(int itemsShowing, int itemsCount)
125     {
126         barScale = cast(float)itemsShowing / itemsCount;
127         setDimensionFromDirection(this.barSize);
128     }
129 
130     this(LinearLayout.Direction direction)
131     {
132         setDirection(direction);
133         thumbFixer = new Widget();
134         thumbFixer.addChild(thumb = new Button(0,0, 50, 50));
135         backward = new Button(0,0, 50, 50);
136         forward = new Button(0,0, 50, 50);
137 
138         addChild(backward, thumbFixer, forward);
139     }
140 }